﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Linq;

namespace Gmantis.Controls.DataGrid
{
    internal static class Extensions
    {
        // Fields
        private static bool _areHandlersSuspended;

        // Methods
        internal static object CreateInstance(this Type type)
        {
            object obj2 = null;
            try
            {
                if (type != null)
                {
                    ConstructorInfo constructor = type.GetConstructor(Type.EmptyTypes);
                    if (constructor != null)
                    {
                        obj2 = constructor.Invoke(null);
                    }
                }
            }
            catch
            {
            }
            return obj2;
        }

        internal static bool DataTypeIsPrimitive(Type dataType)
        {
            if (dataType == null)
            {
                return false;
            }
            if ((!dataType.IsPrimitive && (dataType != typeof(string))) && (dataType != typeof(DateTime)))
            {
                return (dataType == typeof(decimal));
            }
            return true;
        }

        private static Type FindGenericType(Type definition, Type type)
        {
            while ((type != null) && (type != typeof(object)))
            {
                if (type.IsGenericType && (type.GetGenericTypeDefinition() == definition))
                {
                    return type;
                }
                if (definition.IsInterface)
                {
                    foreach (Type type2 in type.GetInterfaces())
                    {
                        Type type3 = FindGenericType(definition, type2);
                        if (type3 != null)
                        {
                            return type3;
                        }
                    }
                }
                type = type.BaseType;
            }
            return null;
        }

        internal static bool GetDataTypeAndProperties(this ICollectionView collView, out Type itemType, out IEnumerable<PropertyInfo> properties)
        {
            itemType = null;
            properties = null;
            IEnumerable sourceCollection = collView.SourceCollection;
            Type enumerableType = sourceCollection.GetType();
            Type dataType = null;
            if (enumerableType.IsEnumerableType())
            {
                Type type3 = enumerableType.GetItemType();
                if ((type3 != typeof(object)) && !type3.FullName.Equals("System.ServiceModel.DomainServices.Client.Entity"))
                {
                    itemType = type3;
                    dataType = itemType;
                }
            }
            if (((itemType == null) || (itemType == typeof(object))) || itemType.GetInterfaces().Contains<Type>(typeof(ICustomTypeProvider)))
            {
                object obj2 = sourceCollection.Cast<object>().FirstOrDefault<object>(delegate(object item)
                {
                    if (item != null)
                    {
                        return item.ToString() != "{NewItemPlaceholder}";
                    }
                    return true;
                });
                if (obj2 != null)
                {
                    itemType = obj2.GetType();
                    dataType = itemType;
                    ICustomTypeProvider provider = obj2 as ICustomTypeProvider;
                    if (provider != null)
                    {
                        dataType = provider.GetCustomType();
                    }
                }
            }
            if (((properties == null) && (dataType != null)) && !DataTypeIsPrimitive(dataType))
            {
                PropertyInfo[] array = dataType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where<PropertyInfo>(delegate(PropertyInfo p)
                {
                    try
                    {
                        return (p.GetIndexParameters().Length == 0);
                    }
                    catch
                    {
                        return true;
                    }
                }).ToArray<PropertyInfo>();
                if (!itemType.GetInterfaces().Contains<Type>(typeof(ICustomTypeProvider)))
                {
                    Array.Sort(array, new DeclarationOrderComparator());
                }
                properties = array;
            }
            return ((itemType != null) && (properties != null));
        }

        public static Control GetFirstFocusableControl(this DependencyObject o)
        {
            if ((o is Control) && ((Control)o).IsTabStop)
            {
                return (Control)o;
            }
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(o); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(o, i);
                if ((child is Control) && ((Control)child).IsTabStop)
                {
                    return (Control)child;
                }
                Control firstFocusableControl = child.GetFirstFocusableControl();
                if (firstFocusableControl != null)
                {
                    return firstFocusableControl;
                }
            }
            return null;
        }

        private static Type GetItemType(this Type enumerableType)
        {
            Type type = FindGenericType(typeof(IEnumerable<>), enumerableType);
            if (type != null)
            {
                return type.GetGenericArguments()[0];
            }
            return enumerableType;
        }

        private static bool IsEnumerableType(this Type enumerableType)
        {
            return (FindGenericType(typeof(IEnumerable<>), enumerableType) != null);
        }

        internal static void SetProperties(this object source, object target)
        {
            if ((source != null) && (target != null))
            {
                List<PropertyInfo> properties = null;
                if (properties == null)
                {
                    properties = source.GetType().GetProperties().ToList<PropertyInfo>();
                }
                source.SetProperties(target, properties);
            }
        }

        internal static void SetProperties(this object source, object target, IList<PropertyInfo> properties)
        {
            if ((source != null) && (target != null))
            {
                for (int i = 0; i < properties.Count; i++)
                {
                    try
                    {
                        if (properties[i].CanRead && properties[i].CanWrite)
                        {
                            properties[i].SetValue(target, properties[i].GetValue(source, null), null);
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }

        public static bool AreHandlersSuspended(this DependencyObject obj)
        {
            return _areHandlersSuspended;
        }

        public static void SetValueNoCallback(this DependencyObject obj, DependencyProperty property, object value)
        {
            _areHandlersSuspended = true;
            try
            {
                obj.SetValue(property, value);
            }
            finally
            {
                _areHandlersSuspended = false;
            }
        }
    }
}
